function Vector(a, b) {
    this.x = a;
    this.y = b;
}

Vector.prototype = {
    rotate: function(b) {
        var a = this.x;
        var c = this.y;
        this.x = Math.cos(b) * a - Math.sin(b) * c;
        this.y = Math.sin(b) * a + Math.cos(b) * c;
        return this
    }, mult: function(a) {
        this.x *= a;
        this.y *= a;
        return this
    }, clone: function() {
        return new Vector(this.x,this.y)
    }, length: function() {
        return Math.sqrt(this.x * this.x + this.y * this.y)
    }, subtract: function(a) {
        this.x -= a.x;
        this.y -= a.y;
        return this
    }, set: function(a, b) {
        this.x = a;
        this.y = b;
        return this
    }
};

function Petal(a, f, b, e, c, d) {
    this.stretchA = a;
    this.stretchB = f;
    this.startAngle = b;
    this.angle = e;
    this.bloom = d;
    this.growFactor = c;
    this.r = 1;
    this.isfinished = false
}

Petal.prototype = {
    draw: function() {
        var a = this.bloom.garden.ctx;
        var e, d, c, b;
        e = new Vector(0, this.r).rotate(Garden.degrad(this.startAngle));
        d = e.clone().rotate(Garden.degrad(this.angle));
        c = e.clone().mult(this.stretchA);
        b = d.clone().mult(this.stretchB);
        a.strokeStyle = this.bloom.c;
        a.beginPath();
        a.moveTo(e.x, e.y);
        a.bezierCurveTo(c.x, c.y, b.x, b.y, d.x, d.y);
        a.stroke()
    }, render: function() {
        if (this.r <= this.bloom.r) {
            this.r += this.growFactor;
            this.draw()
        } else {
            this.isfinished = true
        }
    }
};

function Bloom(e, d, f, a, b) {
    this.p = e;
    this.r = d;
    this.c = f;
    this.pc = a;
    this.petals = [];
    this.garden = b;
    this.init();
    this.garden.addBloom(this)
}

Bloom.prototype = {
    draw: function() {
        var c, b = true;
        this.garden.ctx.save();
        this.garden.ctx.translate(this.p.x, this.p.y);
        for (var a = 0; a < this.petals.length; a++) {
            c = this.petals[a];
            c.render();
            b *= c.isfinished
        }
        this.garden.ctx.restore();
        if (b == true) {
            this.garden.removeBloom(this)
        }
    }, init: function() {
        var c = 360 / this.pc;
        var b = Garden.randomInt(0,90);
        for (var a = 0; a < this.pc; a++) {
            this.petals.push(new Petal(Garden.random(Garden.options.petalStretch.min, Garden.options.petalStretch.max), Garden.random(Garden.options.petalStretch.min, Garden.options.petalStretch.max), b + a * c, c, Garden.random(Garden.options.growFactor.min, Garden.options.growFactor.max), this))
        }
    }
};

function Garden(a, b) {
    this.blooms = [];
    this.element = b;
    this.ctx = a
}

Garden.prototype = {
    render: function() {
        for (var a = 0; a < this.blooms.length; a++) {
            this.blooms[a].draw()
        }
    }, addBloom: function(a) {
        this.blooms.push(a)
    }, removeBloom: function(a) {
        var d;
        for (var c = 0; c < this.blooms.length; c++) {
            d = this.blooms[c];
            if (d === a) {
                this.blooms.splice(c,1);
                return this
            }
        }
    }, createRandomBloom: function(a, b) {
        this.createBloom(a, b, Garden.randomInt(Garden.options.bloomRadius.min, Garden.options.bloomRadius.max), Garden.randomrgba(Garden.options.color.rmin, Garden.options.color.rmax,Garden.options.color.gmin, Garden.options.color.gmax, Garden.options.color.bmin, Garden.options.color.bmax, Garden.options.color.opacity), Garden.randomInt(Garden.options.petalCount.min, Garden.options.petalCount.max))
    }, createBloom: function(a, f, d, e, b) {
        new Bloom(new Vector(a, f), d, e, b, this)
    }, clear: function() {
        this.blooms = [];
        this.ctx.clearRect(0, 0, this.element.width, this.element.height)
    }
};

Garden.options={petalCount:{min:8,max:15},petalStretch:{min:0.1,max:3},growFactor:{min:0.1,max:1},bloomRadius:{min:8,max:10},density:10,growSpeed:1000/60,color:{rmin:128,rmax:255,gmin:0,gmax:128,bmin:0,bmax:128,opacity:0.1},tanAngle:60};Garden.random=function(b,a){return Math.random()*(a-b)+b};Garden.randomInt=function(b,a){return Math.floor(Math.random()*(a-b+1))+b};Garden.circle=2*Math.PI;Garden.degrad=function(a){return Garden.circle/360*a};Garden.raddeg=function(a){return a/Garden.circle*360};Garden.rgba=function(f,e,c,d){return"rgba("+f+","+e+","+c+","+d+")"};Garden.randomrgba=function(i,n,h,m,l,d,k){var c=Math.round(Garden.random(i,n));var f=Math.round(Garden.random(h,m));var j=Math.round(Garden.random(l,d));var e=5;if(Math.abs(c-f)<=e&&Math.abs(f-j)<=e&&Math.abs(j-c)<=e){return Garden.rgba(i,n,h,m,l,d,k)}else{return Garden.rgba(c,f,j,k)}};
